/***************************************************************************
 *          qhhcparser.cpp - CHM hhc file parser                       *
 *                           -------------------                           *
 *                                                                         *
 *  author:     Nestle <zhurx4g@gmail.com>                         *
 *  notes:      This is a quick hhc file parser.           *
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU Lesser General Public License as        *
 *   published by the Free Software Foundation; either version 2.1 of the  *
 *   License, or (at your option) any later version.                       *
 *                                                                         *
 ***************************************************************************/

#include "QHHCParser.h"

QHHCParser::QHHCParser()
{
    depth = 0;
}
QHHCParser::~QHHCParser()
{    

}
void QHHCParser::parse(const QString& fileName,QHHCHandler* handler)
{
    this->handler = handler;
    QFile file(fileName);
    if(!file.open(QFile::ReadOnly)){
        return;
    }
    QTextStream dataStream(&file);
    QChar content;
    while(!dataStream.atEnd()) {
        dataStream>>content;
        if(content==QChar('<')){
            QString temp = readEntity(dataStream);
            if(temp.startsWith("<!--")){
            }else if(temp.startsWith("</")){
                processEndtElement(temp);
            }else{
                QString tagName;
                QMap<QString,QString> map;
                processStartElement(temp,tagName,map);
                if(temp.endsWith("/>",Qt::CaseInsensitive)){
                    processEndtElement(tagName);
                }
            }
        }

    }
}
QString QHHCParser::readEntity(QTextStream& dataStream){
    QString result("<");
    QChar content;
    while(!dataStream.atEnd()) {
        dataStream>>content;
        result.append(content);
        if(content==QChar('>')){
            break;
        }
    }
    return result;
}
bool QHHCParser::processStartElement(const QString& element,QString& tagName,QMap<QString,QString>& attrMap)
{
    QString tmpAttrName;
    QString tmpAttrValue;
    int status =0;//0 read tagname,1 read attr name,2 begin read attr value,3 read attr value,4 read end
    for(int i=0;i<element.length();i++){
        if(element.data()[i]==QChar('<')){
        }else if(element.data()[i]==QChar('>')){

        }else if(element.data()[i]==QChar(' ')){
            if(status==0||status==4){
                status=1;//began attr
            }else if(status==3){
                tmpAttrValue.append(element.at(i));
            }
        }else if(element.data()[i]==QChar('=')){
            status=2;
        }else if(element.data()[i]==QChar('\"')){
            if(status==2){
                status=3;
            }else{
                attrMap.insert(tmpAttrName.toLower(),tmpAttrValue);
                ///QString sttt = QString("%1 %2 %3").arg(tmpAttrName).arg("=").arg(tmpAttrValue);
                ///qDebug(sttt.toLocal8Bit().data());
                tmpAttrName.clear();
                tmpAttrValue.clear();
                status = 4;
            }
        }else if(element.data()[i]==QChar('/')){
            if(status==3){
                tmpAttrValue.append(element.at(i));
                continue;
            }
            break;
        }else{
            if(status==0){
                tagName.append(element.at(i));
            }else if(status==1){
                tmpAttrName.append(element.at(i));
            }else if(status==3){
                tmpAttrValue.append(element.at(i));
            }
        }
    }
    handler->startElement(tagName,attrMap);
    return true;
}
bool QHHCParser::processEndtElement(const QString& element){
    QString tagName;
    for(int i=0;i<element.length();i++){
        if(element.data()[i]==QChar('<')){
        }else if(element.data()[i]==QChar('/')){
        }else if(element.data()[i]==QChar('>')){
        }else{
            tagName.append(element.data()[i]);
        }
    }
    handler->endElement(tagName);
    return true;
}
